// Package test 包含项目的单元测试和集成测试
// 该包提供了对任务相关API的测试用例
package test

import (
	"aigen-todo/internal/models"
	"aigen-todo/internal/service"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
)

// TestTaskAPI 测试任务相关API
func TestTaskAPI(t *testing.T) {

	// 测试用例1：创建任务成功
	t.Run("CreateTaskSuccess", func(t *testing.T) {
		// 为每个测试用例创建独立的mock实例
		mockTaskRepo := new(MockTaskRepository)
		mockTaskGroupRepo := new(MockTaskGroupRepository)
		mockUserRepo := new(MockUserRepository)
		
		// 创建服务
		taskService := service.NewTaskService(mockTaskRepo, mockTaskGroupRepo, mockUserRepo)
		
		// 设置模拟返回值
		userID := uint64(1)
		groupID := uint64(1)
		title := "测试任务"
		description := "测试任务描述"
		isImportant := false
		isMyDay := false
		dueDate := time.Now()

		// 模拟用户存在
		mockUserRepo.On("GetByID", userID).Return(&models.User{
			ID:       userID,
			Username: "testuser",
			Email:    "test@example.com",
		}, nil)

		// 模拟任务分组存在
		mockTaskGroupRepo.On("GetByID", groupID).Return(&models.TaskGroup{
			ID:     groupID,
			UserID: userID,
			Name:   "默认分组",
		}, nil)

		// 模拟创建任务
		mockTaskRepo.On("Create", mock.AnythingOfType("*models.Task")).Return(nil)

		// 直接测试服务层方法
		task, err := taskService.CreateTask(userID, groupID, title, description, isImportant, isMyDay, &dueDate)

		// 验证结果
		assert.NoError(t, err)
		assert.NotNil(t, task)
		assert.Equal(t, title, task.Title)
		assert.Equal(t, description, task.Description)
		assert.Equal(t, isImportant, task.IsImportant)
		assert.Equal(t, isMyDay, task.IsMyDay)
		mockTaskRepo.AssertExpectations(t)
		mockTaskGroupRepo.AssertExpectations(t)
	})

	// 测试用例2：获取任务列表成功
	t.Run("GetTasksSuccess", func(t *testing.T) {
		// 为每个测试用例创建独立的mock实例
		mockTaskRepo := new(MockTaskRepository)
		mockTaskGroupRepo := new(MockTaskGroupRepository)
		mockUserRepo := new(MockUserRepository)
		
		// 创建服务
		taskService := service.NewTaskService(mockTaskRepo, mockTaskGroupRepo, mockUserRepo)
		
		// 测试用例：获取用户任务列表成功
		userID := uint64(1)
		expectedTasks := []models.Task{
			{
				ID:          1,
				UserID:      userID,
				GroupID:     1,
				Title:       "任务1",
				Description: "任务1描述",
				IsImportant: false,
				IsMyDay:     false,
				Status:      models.StatusNew,
				CreatedAt:   time.Now(),
			},
			{
				ID:          2,
				UserID:      userID,
				GroupID:     1,
				Title:       "任务2",
				Description: "任务2描述",
				IsImportant: true,
				IsMyDay:     true,
				Status:      models.StatusInProgress,
				CreatedAt:   time.Now(),
			},
		}

		// 设置模拟返回值
		mockTaskRepo.On("GetByUserID", userID).Return(expectedTasks, nil)

		// 直接测试服务层方法
		tasks, err := taskService.GetTasksByUserID(userID)

		// 验证结果
		assert.NoError(t, err)
		assert.NotNil(t, tasks)
		assert.Len(t, tasks, 2)
		assert.Equal(t, expectedTasks[0].Title, tasks[0].Title)
		assert.Equal(t, expectedTasks[1].Title, tasks[1].Title)
		mockTaskRepo.AssertExpectations(t)
	})

	// 测试用例3：获取单个任务成功
	t.Run("GetTaskSuccess", func(t *testing.T) {
		// 为每个测试用例创建独立的mock实例
		mockTaskRepo := new(MockTaskRepository)
		mockTaskGroupRepo := new(MockTaskGroupRepository)
		mockUserRepo := new(MockUserRepository)
		
		// 创建服务
		taskService := service.NewTaskService(mockTaskRepo, mockTaskGroupRepo, mockUserRepo)
		
		// 设置模拟返回值
		taskID := uint64(1)
		userID := uint64(1)

		// 模拟获取任务
		expectedTask := &models.Task{
			ID:          taskID,
			UserID:      userID,
			GroupID:     1,
			Title:       "测试任务",
			Description: "测试任务描述",
			IsImportant: false,
			IsMyDay:     false,
			Status:      models.StatusNew,
			CreatedAt:   time.Now(),
		}
		mockTaskRepo.On("GetByID", taskID).Return(expectedTask, nil)

		// 直接测试服务层方法
		task, err := taskService.GetTaskByID(taskID)

		// 验证结果
		assert.NoError(t, err)
		assert.NotNil(t, task)
		assert.Equal(t, taskID, task.ID)
		assert.Equal(t, "测试任务", task.Title)
		mockTaskRepo.AssertExpectations(t)
	})
}
